package controller

import (
	"gitee.com/dhcy/video_demo/models"
	"github.com/gin-gonic/gin"
	"net/http"
	"sync"
)

type VideoController interface {
	GetAll(c *gin.Context)
	Update(c *gin.Context)
	Delete(c *gin.Context)
	Create(c *gin.Context)
}

type controller struct {
	videos []*models.Video
	mtx    sync.Mutex
}

func NewVideoController() VideoController {
	return &controller{videos: make([]*models.Video, 0)}
}

type generator struct {
	counter int
	mtx     sync.Mutex
}

func (g *generator) genNextID() int {
	g.mtx.Lock()
	defer g.mtx.Unlock()
	g.counter++
	return g.counter
}

var g = &generator{}

func (v *controller) GetAll(c *gin.Context) {
	c.JSON(http.StatusOK, v.videos)
}

func (v *controller) Update(c *gin.Context) {
	var videoToUpdate models.Video
	// bind uri
	if err := c.ShouldBindUri(&videoToUpdate); err != nil {
		c.String(http.StatusBadRequest, "update video bind err:%v", err)
		return
	}
	// bind json
	if err := c.ShouldBindJSON(&videoToUpdate); err != nil {
		c.String(http.StatusBadRequest, "update video bind err:%v", err)
		return
	}
	for idx, video := range v.videos {
		if video.ID == videoToUpdate.ID {
			v.videos[idx] = &videoToUpdate
			c.String(http.StatusOK, "update video id:%d is ok", videoToUpdate.ID)
			return
		}
	}
	c.String(http.StatusOK, "update video id:%d is nil", videoToUpdate.ID)
}

func (v *controller) Delete(c *gin.Context) {
	var videoToDelete models.Video
	// bind uri
	if err := c.ShouldBindUri(&videoToDelete); err != nil {
		c.String(http.StatusBadRequest, "delete video bind err:%v", err)
		return
	}
	for idx, video := range v.videos {
		if video.ID == videoToDelete.ID {
			v.mtx.Lock()
			v.videos = append(v.videos[0:idx], v.videos[idx+1:len(v.videos)]...)
			v.mtx.Unlock()
			c.String(http.StatusOK, "delete video id:%d is ok", videoToDelete.ID)
			return
		}
	}
	c.String(http.StatusOK, "delete video id:%d is nil", videoToDelete.ID)
}

func (v *controller) Create(c *gin.Context) {
	video := models.Video{}
	if err := c.ShouldBindJSON(&video); err != nil {
		c.String(http.StatusBadRequest, "bind create err:%v", err)
		return
	}
	video.ID = g.genNextID()
	v.videos = append(v.videos, &video)
	c.String(http.StatusOK, "create video is ok id:%d", video.ID)
}
